{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "d54eb496",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "a=torch.zeros(2,3)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "caf00695",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[1., 1., 1., 1.],\n",
      "        [1., 1., 1., 1.],\n",
      "        [1., 1., 1., 1.]])\n"
     ]
    }
   ],
   "source": [
    "b=torch.ones(3,4)\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2fb26f1c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[ 0.4107, -0.1695, -0.1962],\n",
      "        [ 1.1209,  0.8616, -0.1132]])\n"
     ]
    }
   ],
   "source": [
    "c=torch.randn(2,3)\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a09515eb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[1, 2],\n",
      "        [3, 4]])\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "numpy_array=np.array([[1,2],[3,4]])\n",
    "tensor_from_numpy = torch.from_numpy(numpy_array)\n",
    "print(tensor_from_numpy)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "20e3e1e8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[ 0.1834, -0.8414, -1.5885],\n",
      "        [-0.6689, -0.3380,  2.8475]])\n"
     ]
    }
   ],
   "source": [
    "device=torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
    "d=torch.randn(2,3,device=device)\n",
    "print(d)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2bea3a5c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[-0.2232, -0.6499, -0.2311],\n",
      "        [ 0.8953,  1.1790,  0.3757]]) tensor([[ 1.6668, -0.5485,  2.1007],\n",
      "        [-0.0617,  1.0851, -0.4662]])\n"
     ]
    }
   ],
   "source": [
    "e=torch.randn(2,3)\n",
    "f=torch.randn(2,3)\n",
    "print(e,f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fb027870",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[ 1.4436, -1.1984,  1.8695],\n",
      "        [ 0.8336,  2.2641, -0.0905]])\n"
     ]
    }
   ],
   "source": [
    "print(e+f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e9df2403",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[-0.2232,  0.8953],\n",
      "        [-0.6499,  1.1790],\n",
      "        [-0.2311,  0.3757]])\n"
     ]
    }
   ],
   "source": [
    "print(e.t())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1854c924",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([2.])\n"
     ]
    }
   ],
   "source": [
    "tensor_requires_grad= torch.tensor([1.0],requires_grad=True)\n",
    "tensor_result=tensor_requires_grad*2\n",
    "tensor_result.backward()\n",
    "\n",
    "print(tensor_requires_grad.grad)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "058ab43f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[-1.4311,  0.5780,  1.0656],\n",
      "        [-0.8068, -0.6972, -1.3717]], requires_grad=True)\n",
      "tensor(9.9417, grad_fn=<MeanBackward0>)\n"
     ]
    }
   ],
   "source": [
    "x=torch.randn(2,3,requires_grad=True)\n",
    "print(x)\n",
    "\n",
    "y=x+2\n",
    "z=y*y*3\n",
    "out=z.mean()\n",
    "print(out)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a16ecd3c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[0.5689, 2.5780, 3.0656],\n",
      "        [1.1932, 1.3028, 0.6283]], grad_fn=<AddBackward0>)\n"
     ]
    }
   ],
   "source": [
    "print(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "08b77e3f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[ 0.9710, 19.9381, 28.1939],\n",
       "        [ 4.2708,  5.0921,  1.1841]], grad_fn=<MulBackward0>)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "z"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e1c21f0b",
   "metadata": {},
   "outputs": [],
   "source": [
    "out.backward()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a265d016",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[0.5689, 2.5780, 3.0656],\n",
      "        [1.1932, 1.3028, 0.6283]])\n"
     ]
    }
   ],
   "source": [
    "print(x.grad)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "457447c7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[0.8534, 3.8670, 4.5984],\n",
      "        [1.7897, 1.9542, 0.9424]], grad_fn=<DivBackward0>)\n"
     ]
    }
   ],
   "source": [
    "# 手动计算梯度\n",
    "manual_grad = 3 * (x + 2) / 2\n",
    "print(manual_grad)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1f5815bf",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "自动计算的梯度:\n",
      "tensor([[1.8802, 2.1143, 1.8181],\n",
      "        [3.1594, 2.0732, 1.4531]])\n",
      "\n",
      "手动计算的梯度:\n",
      "tensor([[1.8802, 2.1143, 1.8181],\n",
      "        [3.1594, 2.0732, 1.4531]], grad_fn=<AddBackward0>)\n",
      "\n",
      "两者是否接近相等: True\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "\n",
    "x = torch.randn(2, 3, requires_grad=True)\n",
    "y = x + 2\n",
    "z = y * y * 3\n",
    "out = z.mean()\n",
    "out.backward()\n",
    "\n",
    "# 手动计算梯度\n",
    "manual_grad =   (x + 2) \n",
    "\n",
    "# 验证自动计算的梯度与手动计算是否一致\n",
    "print(\"自动计算的梯度:\")\n",
    "print(x.grad)\n",
    "print(\"\\n手动计算的梯度:\")\n",
    "print(manual_grad)\n",
    "print(\"\\n两者是否接近相等:\", torch.allclose(x.grad, manual_grad))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7170d460",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "SimpleNN(\n",
      "  (fc1): Linear(in_features=2, out_features=2, bias=True)\n",
      "  (fc2): Linear(in_features=2, out_features=1, bias=True)\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "import torch.nn as nn\n",
    "import torch.optim as optim\n",
    "\n",
    "class SimpleNN(nn.Module):\n",
    "    def __init__(self):\n",
    "        super(SimpleNN,self).__init__()\n",
    "        self.fc1=nn.Linear(2,2)\n",
    "        self.fc2=nn.Linear(2,1)\n",
    "\n",
    "    def forward(self,x):\n",
    "        x=torch.relu(self.fc1(x))\n",
    "        x=self.fc2(x)\n",
    "        return x\n",
    "\n",
    "model=SimpleNN()\n",
    "print(model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d022303f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[0.3038]], grad_fn=<AddmmBackward0>)\n"
     ]
    }
   ],
   "source": [
    "x=torch.randn(1,2)\n",
    "\n",
    "output=model(x)\n",
    "\n",
    "print(output)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c201e48f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[1.0545, 0.1269]])\n"
     ]
    }
   ],
   "source": [
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d95b4e6a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Parameter containing:\n",
      "tensor([[ 0.5040, -0.4894],\n",
      "        [ 0.3783, -0.2940]], requires_grad=True)\n",
      "Parameter containing:\n",
      "tensor([ 0.5836, -0.5085], requires_grad=True)\n",
      "Parameter containing:\n",
      "tensor([[0.3991, 0.3595]], requires_grad=True)\n",
      "Parameter containing:\n",
      "tensor([-0.1164], requires_grad=True)\n"
     ]
    }
   ],
   "source": [
    "for param in model.parameters():\n",
    "    print(param)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6fac18ba",
   "metadata": {},
   "outputs": [],
   "source": [
    "output=torch.tensor([[3.0]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "29021746",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[3.]]) tensor([[1.]]) tensor(4.)\n"
     ]
    }
   ],
   "source": [
    "criterion=nn.MSELoss(reduction='mean')\n",
    "target=torch.tensor([[1.0]])\n",
    "loss=criterion(output,target)\n",
    "print(output,target,loss)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3d6fe775",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[3.]])"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d0cc1cb5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor(1.2877, grad_fn=<MseLossBackward0>)\n"
     ]
    }
   ],
   "source": [
    "loss = nn.MSELoss()\n",
    "input = torch.randn(3, 5, requires_grad=True)\n",
    "target = torch.randn(3, 5)\n",
    "\n",
    "# 计算损失\n",
    "output2 = loss(input, target)\n",
    "print(output2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "18011b91",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Adam (\n",
      "Parameter Group 0\n",
      "    amsgrad: False\n",
      "    betas: (0.9, 0.999)\n",
      "    capturable: False\n",
      "    decoupled_weight_decay: False\n",
      "    differentiable: False\n",
      "    eps: 1e-08\n",
      "    foreach: None\n",
      "    fused: None\n",
      "    lr: 0.001\n",
      "    maximize: False\n",
      "    weight_decay: 0\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "optimizer=optim.Adam(model.parameters(),lr=0.001)\n",
    "print(optimizer)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5589364b",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "d:\\anaconda\\envs\\torchtest\\Lib\\site-packages\\torch\\nn\\modules\\loss.py:610: UserWarning: Using a target size (torch.Size([3, 5])) that is different to the input size (torch.Size([1, 1])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.\n",
      "  return F.mse_loss(input, target, reduction=self.reduction)\n"
     ]
    }
   ],
   "source": [
    "\n",
    "optimizer.zero_grad()\n",
    "output=model(x)\n",
    "lossv = criterion(output, target)\n",
    "lossv.backward()\n",
    "optimizer.step()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "46d8df90",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Parameter containing:\n",
      "tensor([[ 0.5030, -0.4904],\n",
      "        [ 0.3783, -0.2940]], requires_grad=True)\n",
      "Parameter containing:\n",
      "tensor([ 0.5826, -0.5085], requires_grad=True)\n",
      "Parameter containing:\n",
      "tensor([[0.3981, 0.3595]], requires_grad=True)\n",
      "Parameter containing:\n",
      "tensor([-0.1174], requires_grad=True)\n"
     ]
    }
   ],
   "source": [
    "for param in model.parameters():\n",
    "    print(param)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "51c45cc0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.25568461418151855\n",
      "0.2452569454908371\n",
      "0.2363036572933197\n",
      "0.22804543375968933\n",
      "0.2212677299976349\n",
      "0.21488162875175476\n",
      "0.20911455154418945\n",
      "0.20333531498908997\n",
      "0.1975146234035492\n",
      "0.19162675738334656\n",
      "0.18572327494621277\n",
      "0.1798563450574875\n",
      "0.17408248782157898\n",
      "0.168341726064682\n",
      "0.162649005651474\n",
      "0.15716245770454407\n",
      "0.1513255536556244\n",
      "0.14476598799228668\n",
      "0.1381807029247284\n",
      "0.13163121044635773\n",
      "0.1252700388431549\n",
      "0.11903031170368195\n",
      "0.11298640072345734\n",
      "0.10701362788677216\n",
      "0.10120499134063721\n",
      "0.09563060104846954\n",
      "0.09035930782556534\n",
      "0.08542703092098236\n",
      "0.0808582454919815\n",
      "0.07679375261068344\n",
      "0.07314486801624298\n",
      "0.07010239362716675\n",
      "0.06728102266788483\n",
      "0.06427476555109024\n",
      "0.06099062040448189\n",
      "0.05785920098423958\n",
      "0.05470237135887146\n",
      "0.051565222442150116\n",
      "0.048488833010196686\n",
      "0.04551171511411667\n",
      "0.04266960173845291\n",
      "0.039994124323129654\n",
      "0.03751126676797867\n",
      "0.03523976355791092\n",
      "0.033217642456293106\n",
      "0.03144744783639908\n",
      "0.029887929558753967\n",
      "0.02852608822286129\n",
      "0.0271528922021389\n",
      "0.024867787957191467\n"
     ]
    }
   ],
   "source": [
    "import torch.nn as nn\n",
    "import torch\n",
    "import torch.optim as optim\n",
    "\n",
    "n_in,n_h,n_out,batch_size=20,5,1,10\n",
    "\n",
    "\n",
    "x=torch.randn(batch_size,n_in)\n",
    "y=torch.tensor([[1.0],[0.0],[0.0],[1.0],[1.0],[1.0],[0.0],[0.0],[1.0],[1.0]])\n",
    "\n",
    "model=nn.Sequential(\n",
    "    nn.Linear(n_in,n_h),\n",
    "    nn.ReLU(),\n",
    "    nn.Linear(n_h,n_out),\n",
    "    nn.Sigmoid()\n",
    ")\n",
    "\n",
    "criterion=torch.nn.MSELoss()\n",
    "optimizer = optim.Adam(model.parameters(),lr=0.01)\n",
    "\n",
    "\n",
    "for epoch in range(50):\n",
    "    y_pred=model(x)\n",
    "    loss=criterion(y_pred,y)\n",
    "    print(loss.item())\n",
    "    optimizer.zero_grad()\n",
    "    loss.backward()\n",
    "    optimizer.step()\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4b292a97",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.optim as optim\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "n_samples=100\n",
    "data = torch.randn(n_samples,2)\n",
    "\n",
    "labels = (data[:,0]**2+data[:,1]**2<1).float().unsqueeze(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "af82c754",
   "metadata": {},
   "outputs": [],
   "source": [
    "class SimpleNN(nn.Module):\n",
    "    def __init__(self):\n",
    "        super(SimpleNN,self).__init__()\n",
    "        self.fc1=nn.Linear(2,4)\n",
    "        self.fc2=nn.Linear(2,1)\n",
    "        self.sigmoid=nn.Sigmoid()\n",
    "\n",
    "    def forward(self,x):\n",
    "        # x = torch.relu(self.fc1(x))\n",
    "        x=self.fc2(x)\n",
    "        return x\n",
    "model = SimpleNN()\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dd366e31",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.7609075903892517\n",
      "0.5829087495803833\n",
      "0.45135948061943054\n",
      "0.3563503324985504\n",
      "0.2994202673435211\n",
      "0.27329760789871216\n",
      "0.2656530737876892\n",
      "0.26850882172584534\n",
      "0.2777996361255646\n",
      "0.2897290587425232\n",
      "0.30010664463043213\n",
      "0.3065604269504547\n",
      "0.30893921852111816\n",
      "0.30778852105140686\n",
      "0.303278386592865\n",
      "0.29552650451660156\n",
      "0.28544074296951294\n",
      "0.2746100127696991\n",
      "0.2645341753959656\n",
      "0.2562156021595001\n",
      "0.2503935396671295\n",
      "0.24770168960094452\n",
      "0.24828031659126282\n",
      "0.2513755261898041\n",
      "0.25555750727653503\n",
      "0.25942304730415344\n",
      "0.2620575726032257\n",
      "0.26300081610679626\n",
      "0.26211676001548767\n",
      "0.2596691846847534\n",
      "0.25637006759643555\n",
      "0.25309306383132935\n",
      "0.25045546889305115\n",
      "0.24868154525756836\n",
      "0.24777311086654663\n",
      "0.24764496088027954\n",
      "0.24808944761753082\n",
      "0.24877995252609253\n",
      "0.24943256378173828\n",
      "0.2499316781759262\n",
      "0.2502565085887909\n",
      "0.2503565847873688\n",
      "0.2501714527606964\n",
      "0.24972259998321533\n",
      "0.24910594522953033\n",
      "0.24841560423374176\n",
      "0.2477387934923172\n",
      "0.2471979558467865\n",
      "0.24691461026668549\n",
      "0.24691860377788544\n",
      "0.24713368713855743\n",
      "0.24744658172130585\n",
      "0.24775007367134094\n",
      "0.24794287979602814\n",
      "0.24795667827129364\n",
      "0.24780148267745972\n",
      "0.24755315482616425\n",
      "0.2472921758890152\n",
      "0.24707351624965668\n",
      "0.24693407118320465\n",
      "0.24688750505447388\n",
      "0.24691124260425568\n",
      "0.24696561694145203\n",
      "0.24702516198158264\n",
      "0.2470780611038208\n",
      "0.2471112608909607\n",
      "0.24711517989635468\n",
      "0.24709229171276093\n",
      "0.24704885482788086\n",
      "0.24698859453201294\n",
      "0.24692195653915405\n",
      "0.24686744809150696\n",
      "0.24683842062950134\n",
      "0.24683651328086853\n",
      "0.2468569576740265\n",
      "0.2468898743391037\n",
      "0.24691930413246155\n",
      "0.2469320148229599\n",
      "0.24692557752132416\n",
      "0.24690532684326172\n",
      "0.24687854945659637\n",
      "0.24685391783714294\n",
      "0.24683868885040283\n",
      "0.24683384597301483\n",
      "0.24683600664138794\n",
      "0.24684202671051025\n",
      "0.24684907495975494\n",
      "0.24685430526733398\n",
      "0.2468564361333847\n",
      "0.24685582518577576\n",
      "0.24685245752334595\n",
      "0.24684634804725647\n",
      "0.24683919548988342\n",
      "0.24683307111263275\n",
      "0.24682924151420593\n",
      "0.2468286007642746\n",
      "0.2468310296535492\n",
      "0.24683481454849243\n",
      "0.24683786928653717\n",
      "0.24683904647827148\n"
     ]
    }
   ],
   "source": [
    "criterion=nn.MSELoss()\n",
    "\n",
    "optimizer = optim.Adam(model.parameters(),lr=0.1)\n",
    "\n",
    "epochs=100\n",
    "\n",
    "for epoch in range(epochs):\n",
    "    outputs=model(data)\n",
    "    loss = criterion(outputs,labels)\n",
    "    optimizer.zero_grad()\n",
    "    loss.backward()\n",
    "    optimizer.step()\n",
    "    print(loss.item())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "26d25b38",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([3., 4.]), tensor(0.))"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import torch\n",
    "\n",
    "from torch.utils.data import Dataset\n",
    "class  MyDataset(Dataset):\n",
    "    def __init__(self,x_data,y_data):\n",
    "        self.x_data=x_data\n",
    "        self.y_data=y_data\n",
    "\n",
    "    def __len__(self):\n",
    "        return len(self.x_data)\n",
    "    \n",
    "    def __getitem__(self,idx):\n",
    "        x=torch.tensor(self.x_data[idx],dtype=torch.float32)\n",
    "        y=torch.tensor(self.y_data[idx],dtype=torch.float32)\n",
    "\n",
    "        return x,y\n",
    "    \n",
    "x_data =[[1,2],[3,4],[5,6],[7,8]]\n",
    "y_data=[1,0,1,0]\n",
    "\n",
    "dataset=MyDataset(x_data,y_data)\n",
    "dataset[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "90e397ff",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "0 tensor([[1., 2.]]) tensor([1.])\n",
      "1 tensor([[5., 6.]]) tensor([1.])\n",
      "2 tensor([[3., 4.]]) tensor([0.])\n",
      "3 tensor([[7., 8.]]) tensor([0.])\n"
     ]
    }
   ],
   "source": [
    "from torch.utils.data import DataLoader\n",
    "dataloader=DataLoader(dataset,batch_size=1,shuffle=True)\n",
    "\n",
    "for epoch in range(1):\n",
    "    print(epoch)\n",
    "    for batch_id,(inputs,labels) in enumerate(dataloader):\n",
    "        print(batch_id,inputs,labels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "88dec42b",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torchvision.datasets as datasets\n",
    "import torchvision.transforms as transforms\n",
    "\n",
    "transforms=transforms.Compose([\n",
    "    transforms.ToTensor(),\n",
    "    transforms.Normalize((0.5,),(0.5,))\n",
    "])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "447ec1d5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Episode: 0, Total Reward: 13.0\n",
      "Episode: 10, Total Reward: 12.0\n",
      "Episode: 20, Total Reward: 11.0\n",
      "Episode: 30, Total Reward: 10.0\n",
      "Episode: 40, Total Reward: 12.0\n",
      "Episode: 50, Total Reward: 12.0\n",
      "Episode: 60, Total Reward: 58.0\n",
      "Episode: 70, Total Reward: 52.0\n",
      "Episode: 80, Total Reward: 122.0\n",
      "Episode: 90, Total Reward: 146.0\n",
      "Episode: 100, Total Reward: 210.0\n",
      "Episode: 110, Total Reward: 196.0\n",
      "Episode: 120, Total Reward: 160.0\n",
      "Episode: 130, Total Reward: 167.0\n",
      "Episode: 140, Total Reward: 96.0\n"
     ]
    },
    {
     "ename": "KeyboardInterrupt",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mKeyboardInterrupt\u001b[39m                         Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[4]\u001b[39m\u001b[32m, line 97\u001b[39m\n\u001b[32m     94\u001b[39m total_reward = \u001b[32m0\u001b[39m\n\u001b[32m     96\u001b[39m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m done:\n\u001b[32m---> \u001b[39m\u001b[32m97\u001b[39m     action = \u001b[43magent\u001b[49m\u001b[43m.\u001b[49m\u001b[43mselect_action\u001b[49m\u001b[43m(\u001b[49m\u001b[43mstate\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m     98\u001b[39m     next_state, reward, done, _,_ = env.step(action)\n\u001b[32m     99\u001b[39m     replay_buffer.append((state, action, reward, next_state, done))\n",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[4]\u001b[39m\u001b[32m, line 48\u001b[39m, in \u001b[36mQLearningAgent.select_action\u001b[39m\u001b[34m(self, state)\u001b[39m\n\u001b[32m     46\u001b[39m state = torch.FloatTensor(state)\n\u001b[32m     47\u001b[39m q_values = \u001b[38;5;28mself\u001b[39m.q_network(state)\n\u001b[32m---> \u001b[39m\u001b[32m48\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mtorch\u001b[49m\u001b[43m.\u001b[49m\u001b[43margmax\u001b[49m\u001b[43m(\u001b[49m\u001b[43mq_values\u001b[49m\u001b[43m)\u001b[49m.item()\n",
      "\u001b[31mKeyboardInterrupt\u001b[39m: "
     ]
    }
   ],
   "source": [
    "import gymnasium as gym\n",
    "import random\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.optim as optim\n",
    "import torch.nn.functional as F\n",
    " \n",
    "# 定义Q网络\n",
    "class QNetwork(nn.Module):\n",
    "    def __init__(self, state_dim, action_dim):\n",
    "        super(QNetwork, self).__init__()\n",
    "        self.fc1 = nn.Linear(state_dim, 64)\n",
    "        self.fc2 = nn.Linear(64, 64)\n",
    "        self.fc3 = nn.Linear(64, action_dim)\n",
    " \n",
    "    def forward(self, x):\n",
    "        x = F.relu(self.fc1(x))\n",
    "        x = F.relu(self.fc2(x))\n",
    "        x = self.fc3(x)\n",
    "        return x\n",
    " \n",
    "# Q-learning算法\n",
    "class QLearningAgent:\n",
    "    def __init__(self, state_dim, action_dim, gamma, epsilon):\n",
    "        self.state_dim = state_dim\n",
    "        self.action_dim = action_dim\n",
    "        self.gamma = gamma  # 折扣因子\n",
    "        self.epsilon = epsilon  # 探索率\n",
    " \n",
    "        # 初始化Q网络和目标网络\n",
    "        self.q_network = QNetwork(state_dim, action_dim)\n",
    "        self.target_network = QNetwork(state_dim, action_dim)\n",
    "        self.target_network.load_state_dict(self.q_network.state_dict())\n",
    "        self.target_network.eval()\n",
    " \n",
    "        self.optimizer = optim.Adam(self.q_network.parameters())\n",
    "        self.loss_fn = nn.MSELoss()\n",
    " \n",
    "    def update_target_network(self):\n",
    "        self.target_network.load_state_dict(self.q_network.state_dict())\n",
    " \n",
    "    def select_action(self, state):\n",
    "        if random.random() < self.epsilon:\n",
    "            return random.randint(0, self.action_dim - 1)\n",
    "        else:\n",
    "            state = torch.FloatTensor(state)\n",
    "            q_values = self.q_network(state)\n",
    "            return torch.argmax(q_values).item()\n",
    " \n",
    "    def train(self, replay_buffer, batch_size):\n",
    "        if len(replay_buffer) < batch_size:\n",
    "            return\n",
    " \n",
    "        # 从回放缓存中采样一个小批量样本\n",
    "        samples = random.sample(replay_buffer, batch_size)\n",
    "        states, actions, rewards, next_states, dones = zip(*samples)\n",
    " \n",
    "        states = torch.FloatTensor(states)\n",
    "        actions = torch.LongTensor(actions)\n",
    "        rewards = torch.FloatTensor(rewards)\n",
    "        next_states = torch.FloatTensor(next_states)\n",
    "        dones = torch.FloatTensor(dones)\n",
    " \n",
    "        # 计算当前状态的Q值\n",
    "        q_values = self.q_network(states)\n",
    "        q_values = q_values.gather(1, actions.unsqueeze(1)).squeeze(1)\n",
    " \n",
    "        # 计算下一个状态的Q值\n",
    "        next_q_values = self.target_network(next_states).max(1)[0]\n",
    "        expected_q_values = rewards + self.gamma * next_q_values * (1 - dones)\n",
    " \n",
    "        # 计算损失并更新Q网络\n",
    "        loss = self.loss_fn(q_values, expected_q_values.detach())\n",
    "        self.optimizer.zero_grad()\n",
    "        loss.backward()\n",
    "        self.optimizer.step()\n",
    " \n",
    "# 创建环境\n",
    "env = gym.make('CartPole-v1')\n",
    "state_dim = env.observation_space.shape[0]\n",
    "action_dim = env.action_space.n\n",
    " \n",
    "# 创建Q-learning智能体\n",
    "agent = QLearningAgent(state_dim, action_dim, gamma=0.99, epsilon=0.2)\n",
    " \n",
    "# 训练\n",
    "replay_buffer = []\n",
    "episodes = 1000\n",
    "batch_size = 32\n",
    " \n",
    "for episode in range(episodes):\n",
    "    state = env.reset()[0]\n",
    "    done = False\n",
    "    total_reward = 0\n",
    " \n",
    "    while not done:\n",
    "        action = agent.select_action(state)\n",
    "        next_state, reward, done, _,_ = env.step(action)\n",
    "        replay_buffer.append((state, action, reward, next_state, done))\n",
    " \n",
    "        state = next_state\n",
    "        total_reward += reward\n",
    " \n",
    "        agent.train(replay_buffer, batch_size)\n",
    " \n",
    "    if episode % 10 == 0:\n",
    "        agent.update_target_network()\n",
    "        print(f\"Episode: {episode}, Total Reward: {total_reward}\")\n",
    " \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "172e61f6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test Total Reward: 172.0\n"
     ]
    }
   ],
   "source": [
    "# 使用训练好的智能体进行测试\n",
    "env = gym.make('CartPole-v1',render_mode='human')\n",
    "state = env.reset()[0]\n",
    "done = False\n",
    "total_reward = 0\n",
    "import time\n",
    "time.sleep(1)\n",
    "while not done:\n",
    "    # time.sleep(1)\n",
    "    env.render()\n",
    "\n",
    "    action = agent.select_action(state)\n",
    "    state, reward, done, _,_ = env.step(action)\n",
    "    total_reward += reward\n",
    " \n",
    "print(f\"Test Total Reward: {total_reward}\")\n",
    " \n",
    "env.close()\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "CX",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
